/* 
 * File:   OperacionSecuencial.cpp
 * Author: maximiliano
 * 
 * Created on 15 de junio de 2013, 17:20
 */

#include "client_OperacionSecuencial.h"
#include "common_MutexScopeLocker.h"

using namespace TP;
using namespace TP::Operaciones;

OperacionSecuencial::OperacionSecuencial(const uint32_t &pId) : Operacion(pId) {}

OperacionSecuencial::~OperacionSecuencial() {}

Operacion* OperacionSecuencial::AgregarOperacion (Operacion* pOperacion){
    if (NULL != pOperacion)
    {
        _operaciones.push_back(pOperacion);
    }
    return pOperacion;
}

void OperacionSecuencial::ejecutar(){
    
    if (_operaciones.size() > 0)
    {
        this->setFinalizada(false);
        _operaciones[0]->ejecutar();
    }
    else
    {
        this->setFinalizada(true);
    }
}

void OperacionSecuencial::procesarRespuesta (vector<string> &pRespuesta){
    
    // Itero las operaciones buscando la operacion pripietaria de la respuesta
    // (en funcion del token).
    
    vector<Operacion*>::iterator it = _operaciones.begin();
    
    while (it < _operaciones.end())
    {
        if ((*it)->asociado(pRespuesta))
        {
            // La operacion actual es la propietaria segun el token.

            (*it)->procesarRespuesta(pRespuesta);
            
            if ((*it)->finalizada())
            {
                // Tras el proceso de la respuesta la operacion se encuentra
                // finalizada.  Ejecuto la siguiente operacion.
                it++;
                if (it < _operaciones.end())
                {
                    (*it)->ejecutar();
                }
                else
                {
                    this->setFinalizada(true);
                }
            }
            break;
        }
        it++;
    }
}

bool OperacionSecuencial::asociado(vector<string> &pRespuesta){
    
    bool asociado = false;
    
    vector<Operacion*>::iterator it = _operaciones.begin();
    
    while (it < _operaciones.end() && !asociado)
    {
        asociado = (*it)->asociado(pRespuesta);
        it++;
    }
    
    return asociado;    
}       

bool OperacionSecuencial::finalizada(){
    
    bool finalizada = true;
    
    vector<Operacion*>::iterator it = _operaciones.begin();
    
    while (it < _operaciones.end() && finalizada)
    {
        finalizada = (*it)->finalizada();
        it++;
    }
    
    return finalizada;
}

bool OperacionSecuencial::setFinalizada(bool pEstado){
    
    MutexScopeLocker locker (_finalizadaMutex);
    
    vector<Operacion*>::iterator it = _operaciones.begin();
    while (it < _operaciones.end()){
        (*it)->setFinalizada(pEstado);
        it++;
    }
    
    Operacion::setFinalizada(pEstado);
    
    return pEstado;
}